package com.waves.camear;

import org.bytedeco.javacv.*;
import org.bytedeco.javacv.Frame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.bytedeco.ffmpeg.global.avcodec.AV_CODEC_ID_H264;

public class JavaCVWebcamRecorder extends JFrame {

    private CanvasFrame canvasFrame;
    private JButton recordButton;
    private JLabel statusLabel;
    private OpenCVFrameGrabber grabber;
    private FrameRecorder recorder;
    private volatile boolean running = true;
    private AtomicBoolean recording = new AtomicBoolean(false);
    private String outputFilename = "output.mp4";

    public JavaCVWebcamRecorder() {
        super("JavaCV 摄像头录像");

        // 1. 初始化 OpenCVFrameGrabber
        grabber = new OpenCVFrameGrabber(0);
        try {
            grabber.start();
        } catch (FrameGrabber.Exception e) {
            JOptionPane.showMessageDialog(this, "无法启动摄像头: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }

        // 2. 初始化 CanvasFrame
        canvasFrame = new CanvasFrame("摄像头");
        canvasFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        canvasFrame.setCanvasSize(grabber.getImageWidth(), grabber.getImageHeight());

        // 3. 初始化 FrameRecorder
        try {
            recorder = FrameRecorder.createDefault(outputFilename, grabber.getImageWidth(), grabber.getImageHeight());
            recorder.setVideoCodec(AV_CODEC_ID_H264);
            recorder.setImageWidth(1280);
            recorder.setImageHeight(720);
            recorder.setFormat("mp4");
            recorder.setFrameRate(30);
            recorder.start();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "无法启动录像器: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            try {
                grabber.stop();
                grabber.close();
            } catch (org.bytedeco.javacv.FrameGrabber.Exception ex) {
                ex.printStackTrace();
            }
            System.exit(1);
        }

        // 4. 创建录像按钮
        recordButton = new JButton("开始录像");
        recordButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                toggleRecording();
            }
        });

        // 5. 状态标签
        statusLabel = new JLabel("摄像头准备就绪");
        statusLabel.setHorizontalAlignment(SwingConstants.CENTER);

        // 6. 布局 UI
        JPanel controlPanel = new JPanel(new FlowLayout());
        controlPanel.add(recordButton);

        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.add(controlPanel, BorderLayout.SOUTH);
        mainPanel.add(statusLabel, BorderLayout.NORTH);

        getContentPane().add(mainPanel);

        // 7. 窗口设置
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);

        // 8. 启动抓取线程
        new Thread(() -> {
            try {
                while (running) {
                    Frame frame = grabber.grab();
                    if (frame != null) {
                        canvasFrame.showImage(frame);

                        if (recording.get()) {
                            try {
                                recorder.record(frame);
                            } catch (Exception e) {
                                statusLabel.setText("录像时发生错误: " + e.getMessage());
                                stopRecording();
                                e.printStackTrace(); // 打印堆栈信息
                            }
                        }

                    } else {
                        // 如果抓取失败，尝试重新启动抓取器
                        try {
                            grabber.restart();
                        } catch (org.bytedeco.javacv.FrameGrabber.Exception e) {
                            statusLabel.setText("摄像头故障: " + e.getMessage());
                            running = false;
                            break;
                        }
                    }
                    Thread.sleep(30);
                }
            } catch (org.bytedeco.javacv.FrameGrabber.Exception | InterruptedException e) {
                statusLabel.setText("抓取线程错误: " + e.getMessage());
            } finally {
                cleanup();
            }
        }).start();
    }

    private void toggleRecording() {
        if (recording.get()) {
            stopRecording();
        } else {
            startRecording();
        }
    }

    private void startRecording() {
        recording.set(true);
        recordButton.setText("停止录像");
        statusLabel.setText("正在录像...");
    }

    private void stopRecording() {
        recording.set(false);
        recordButton.setText("开始录像");
        statusLabel.setText("录像已停止");
    }

    private void cleanup() {
        running = false;
        try {
            if (recorder != null) {
                recorder.stop();
                recorder.close();
            }
            if (grabber != null) {
                grabber.stop();
                grabber.close();
            }
        } catch (IOException e){
            e.printStackTrace();
        }
        if (canvasFrame != null) {
            canvasFrame.dispose();
        }

    }

    @Override
    public void dispose() {
        cleanup();
        super.dispose();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(JavaCVWebcamRecorder::new);
    }
}